﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;

namespace ClearingRestartingAutomaton.Base
{
    /// <summary>
    /// The structure InstructionStepCollection encapsulates the enumeration of (all) InstructionStep 
    /// structures that can be applied to the given input word in the specified context.
    /// Only one of the two possible ways how to apply the instructions is used.
    /// </summary>
    [Serializable]
    public struct InstructionStepCollection
    {
        #region Constructors

        /// <summary>
        /// Constructor of this structure.
        /// </summary>
        /// <param name="word">The word to which the instructions were applied.</param>
        /// <param name="leftContext">The left context of the given input word.</param>
        /// <param name="rightContext">The right context of the given input word.</param>
        /// <param name="instructionUse">The way the instructions were used.</param>
        /// <param name="instructionSteps">
        /// The enumeration of (all) InstructionStep structures that can be applied 
        /// to the given input word in the specified context.
        /// </param>
        public InstructionStepCollection(
            string word,
            string leftContext,
            string rightContext,
            InstructionUse instructionUse,
            IEnumerable<InstructionStep> instructionSteps)
        {
            this.word = word;
            this.leftContext = leftContext;
            this.rightContext = rightContext;
            this.use = instructionUse;
            this.steps = new List<InstructionStep>(instructionSteps);
        }
        #endregion

        #region Public Properties

        /// <summary>
        /// The word to which the instructions were applied.
        /// </summary>
        public string Word
        {
            get { return this.word; }
        }

        /// <summary>
        /// The left context of the given input word.
        /// </summary>
        public string LeftContext
        {
            get { return this.leftContext; }
        }

        /// <summary>
        /// The right context of the given input word.
        /// </summary>
        public string RightContext
        {
            get { return this.rightContext; }
        }

        /// <summary>
        /// The way the instructions were used.
        /// </summary>
        public InstructionUse Use
        {
            get { return this.use; }
        }

        /// <summary>
        /// Gets the enumeration of (all) instructions that can be applied 
        /// to the given input word in the specified context.
        /// </summary>
        public ReadOnlyCollection<InstructionStep> Steps
        {
            get { return this.steps.AsReadOnly(); }
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Returns a System.String that represents this collection of instruction steps.
        /// </summary>
        /// <returns>A System.String that represents this collection of instruction steps.</returns>
        public override string ToString()
        {
            StringBuilder stringBuilder = new StringBuilder();
            foreach (InstructionStep instructionStep in this.steps)
            {
                stringBuilder.AppendLine(instructionStep.ToString());
            }
            return stringBuilder.ToString();
        }

        #endregion

        #region Private Data Members

        private string word;
        private string leftContext;
        private string rightContext;
        private InstructionUse use;
        private List<InstructionStep> steps;

        #endregion
    }
}
